namespace EyeOpen.DddOrm.Data.Test
{
	using System;
	using System.Linq;

	using EyeOpen.Domain;

	using EyeOpen.Domain.Transactional;

	using NHibernate;

	using NHibernate.Linq;

	internal class NhibernateDataSession
		: ITransactionalCollection
	{
		private readonly ISession session;

		public NhibernateDataSession(ISession session)
		{
			this.session = session;
		}

		public void Add<T>(T entity)
			where T : class, IAggregateRoot
		{
			session.Save(entity);
		}

		public void Update<T>(T entity)
			where T : class, IAggregateRoot
		{
			session.Merge(entity);
		}

		public IQueryable<T> Query<T>()
			where T : class, IAggregateRoot
		{
			return
				session
					.Query<T>()
					.Cacheable();
		}

		public T GetByKey<T>(IComparable key)
			where T : class, IAggregateRoot
		{
			return
				session.Get<T>(key);
		}

		public void Delete<T>(T entity)
			where T : class, IAggregateRoot
		{
			var entityToDelete =
				session
				.Load<T>(entity.Id);

			session.Delete(entityToDelete);
		}

		public void Commit()
		{
			var transaction = session.BeginTransaction();

			try
			{
				transaction.Commit();
			}
			catch
			{
				transaction.Rollback();
				throw;
			}
			finally
			{
				if (transaction != null)
				{
					transaction.Dispose();
				}
			}
		}

		public void Dispose()
		{
			session.Dispose();
		}
	}
}